<?php
// +----------------------------------------------------------------------
// | HkCms 栏目模型
// +----------------------------------------------------------------------
// | Copyright (c) 2012-2019 http://www.hkcms.cn, All rights reserved.
// +----------------------------------------------------------------------
// | Author: 广州恒企教育科技有限公司 <admin@hkcms.cn>
// +----------------------------------------------------------------------
namespace app\content\model;

use common\model\Model as CommModel;
use libs\util\Dir;
use think\Cache;
use \think\Db;
use \think\Validate;
use app\content\validate\Category as CValidate;
use app\content\model\Content as ContentModel;

class Category extends CommModel
{   
    public $error = '';

    /**
     * 添加栏目
     * @param type $data 页面提交数据
     * @return boolean]
     */
    public function addCategory($post) {

        if (empty($post)) {

            $this->error = '添加栏目数据不能为空！';

            return false;
        }

        $data = $post['info'];

        //栏目类型
        $data['type'] = isset($post['type'])?(int) $post['type']:'';

        //表单令牌
        // $data[config("TOKEN_NAME")] = $post[config("TOKEN_NAME")];
        $post['setting'] = isset($post['setting'])?$post['setting']:array();
        $data['setting'] = $post['setting'];

        //终极栏目设置
        if (!isset($data['child'])) {

            $data['child'] = 1;
        }

        $data['setting']['ishtml'] =isset($data['setting']['ishtml'])?$data['setting']['ishtml']:'';
        //栏目生成静态配置
        if ( $data['setting']['ishtml'] ) {

            $data['setting']['category_ruleid'] = $post['category_html_ruleid'];

        } else {
            $post['category_php_ruleid'] = isset($post['category_php_ruleid'])?$post['category_php_ruleid']:'';
            $data['setting']['category_ruleid'] = $post['category_php_ruleid'];
        }

        //栏目是否生成静态
        $data['sethtml'] = $data['setting']['ishtml'] ? 1: 0;

        $data['setting']['content_ishtml'] = isset($data['setting']['content_ishtml'])?$data['setting']['content_ishtml']:'';
        if ( $data['setting']['content_ishtml'] ) {

            $data['setting']['show_ruleid'] = $post['show_html_ruleid'];

        } else {
            $post['show_php_ruleid'] = isset($post['show_php_ruleid'])?$post['show_php_ruleid']:'';
            $data['setting']['show_ruleid'] = $post['show_php_ruleid'];
        }
    

        $CValidate = new CValidate;

        //判断URL规则是否有设置
        if ((int)$data['type'] == 0) {//内部栏目

            if (empty($data['setting']['category_ruleid'])) {

                $this->error = '栏目URL规则没有设置！';

                return false;
            }

            if (empty($data['setting']['show_ruleid']) && $data['child']) {

                $this->error = '栏目内容页URL规则没有设置！';

                return false;
            }

            //添加modelid自动验证规则
            // array_unshift($this->_validate, array('modelid', 'require', '所属模型不能为空！', 1, 'regex', 3));
            $CValidate->rule(['modelid'   => 'require']);

        } else if ((int)$data['type'] == 1) {//单页栏目

            if (empty($data['setting']['category_ruleid'])) {
                $this->error = '栏目URL规则没有设置！';
                return false;
            }
        }

        load('content/iconvfunc');

        //栏目拼音
        $catname = iconv('utf-8', 'gbk', $data['catname']);

        $letters = gbk_to_pinyin($catname);

        $data['letter'] = strtolower(implode('', $letters));

        //序列化setting数据
        $data['setting'] = serialize($data['setting']);

        // 验证数据
        $result = $CValidate->check($data);

        if (!$result) {

            $this->error = $CValidate->getError();

            return false;
        }

        if ((int)$data['type'] != 2) {
            //绑定域名
            $data['domain'] = $data['url'];
        }

        $data['module'] = 'content';

        //添加数据
        $catid = $this->insertGetId($data);

        if ($catid) {

            //更新缓存
            hk_cache('Category', NULL); 
            $Dir = new \libs\util\Dir('');
            $Dir->delDir(RUNTIME_PATH . "cache/");
            $Dir->delDir(RUNTIME_PATH . "temp/");
            //更新开启其他方式的缓存
            \think\Cache::clear();

            // 修复栏目 添加parentdir
            $repair =  new \app\content\controller\Category;
            $data = $this->get($catid)->toarray();
            self::repair([ $catid => $data]);

            if ( $data['sethtml'] == 1 ) {

                $html = new \libs\system\Html;

                $html->category($catid, '1');
            }

            //更新附件状态
            if ( isset($data['image'])&&!empty($data['image']) ) {

                //更新附件状态，把相关附件和文章进行管理
                service("Attachment")->api_update('', 'catid-' . $catid, 1);
            }
            //扩展字段处理
            if ( isset($post['extend'])&&!empty($post['extend']) ) {

                $this->extendField($catid, $post);
            }

            return $catid;

        } else {

            $this->error = '栏目添加失败！';

            return false;
        }
      
    }

    /**
     * 编辑栏目
     * @param type $post 页面提交过来的数据
     * @return boolean
     */
    public function editCategory($post) 
    {
        if (empty($post)) {
            $this->error = '添加栏目数据不能为空！';
            return false;
        }
        $catid = $post['catid'];
        $data = $post['info'];
        //查询该栏目是否存在
        $info = $this->where(array('catid' => $catid))->find();
        if (is_object($info)) {
            $info = $info->toArray();
        }
        if (empty($info)) {
            $this->error = '该栏目不存在！';
            return false;
        }
        // $l_parentid = $info['parentid'];
        unset($data['catid'], $info['catid'], $data['module'], $data['child']);
        // //表单令牌
        // $data[C("TOKEN_NAME")] = $post[C("TOKEN_NAME")];
        $data['setting'] = isset($post['setting'])?$post['setting']:array();

        $content_ishtml = isset($data['setting']['content_ishtml']);
        //内部栏目
        if ((int)$info['type'] != 2) {
            if ($data['setting']['ishtml']) {
                $data['setting']['category_ruleid'] = $post['category_html_ruleid'];
            } else {
                $data['setting']['category_ruleid'] = isset($post['category_php_ruleid'])?$post['category_php_ruleid']:'';
                $data['url'] = '';
            }
        }
        //栏目生成静态配置
        if (isset($data['setting']['ishtml'])&&$data['setting']['ishtml']) {
            $data['setting']['category_ruleid'] = $post['category_html_ruleid'];
        } else {
            $data['setting']['category_ruleid'] = isset($post['category_php_ruleid'])?$post['category_php_ruleid']:'';
        }
        //内容生成静态配置
        // if ($data['setting']['content_ishtml']) {
        if (isset($data['setting']['content_ishtml'])&&$data['setting']['content_ishtml']) {
            $data['setting']['show_ruleid'] = $post['show_html_ruleid'];
        } else {
            // $data['setting']['show_ruleid'] = $post['show_php_ruleid'];
            $data['setting']['show_ruleid'] = isset($post['show_php_ruleid'])?$post['show_php_ruleid']:'';
        }
        //栏目是否生成静态
        $data['sethtml'] = isset($data['setting']['ishtml']) ? $data['setting']['ishtml'] : 0;
        //判断URL规则是否有设置
        if ((int)$info['type'] == 0) {//内部栏目
            if (empty($data['setting']['category_ruleid'])) {
                $this->error = '栏目URL规则没有设置！';
                return false;
            }
            // if (empty($data['setting']['show_ruleid']) && $data['child']) {
            if (empty($data['setting']['show_ruleid']) && isset($data['child'])) {
                $this->error = '栏目内容页URL规则没有设置！';
                return false;
            }
            //添加modelid自动验证规则
            // array_unshift($this->_validate, array('modelid', 'require', '所属模型不能为空！', 1, 'regex', 3));
            if (!isset($data['modelid']) || empty($data['modelid'])) {

                $this->error = '所属模型不能为空！';

                return false;
            }

        } else if ((int)$info['type'] == 1) {//单页栏目
            if (empty($data['setting']['category_ruleid'])) {
                $this->error = '栏目URL规则没有设置！';
                return false;
            }
        }
        load('content/iconvfunc');
        //栏目拼音
        $catname = iconv('utf-8', 'gbk', $data['catname']);
        $letters = gbk_to_pinyin($catname);
        $data['letter'] = strtolower(implode('', $letters));
        //序列化setting数据
        $data['setting'] = serialize($data['setting']);

        $CValidate = new CValidate;

        $result = $CValidate->check($data);

        if (!$result) {

            $this->error = $CValidate->getError();

            return false;
        }

        if ((int)$info['type'] != 2) {
            //绑定域名
            $data['domain'] = $data['url'];
        }
        if ($this->where(array("catid" => $catid))->update($data) !== false) {

            //更新缓存
            hk_cache('Category', NULL);
            
            getCategory($catid, '', true);

            $html = new \libs\system\Html;

            $modelid = $this->where(array("catid" => $catid))->value('modelid');
            if (!empty($modelid)) {
                // 生成内容开始
                $model = ContentModel::getInstance($modelid);
                $where = array();
                $where['status'] = array("EQ", 99);
                $where['catid'] = array("EQ", $catid);
                $data = $model->relation(true)->where($where)->select()->toarray();
                foreach ($data as $r) {
                    if ($r['islink'])
                        continue;
                    //更新URL链接
                    $this->urls($r);
                    $html->show($r);
                }
            }

            $html->category($catid);

            //更新附件状态
            if ( isset($data['image']) ) {
                //更新附件状态，把相关附件和文章进行管理
                service("Attachment")->api_update('', 'catid-' . $catid, 1);
            }

            //扩展字段处理
            if (isset($post['extend'])) {
                $result = $this->extendField($catid, $post);

                if ( !$result ) {
                    return false;
                }
            }

            // 更新模板缓存
            $Dir = new Dir('');
            $Dir->delDir(RUNTIME_PATH . "cache/");
            $Dir->delDir(RUNTIME_PATH . "temp/");

            return true;
        } else {
            $this->error = '栏目修改失败！';
            return false;
        }
     
    }

    /**
     * 删除栏目，如果有子栏目，会删除对应的子目录
     * @param type $catid 可以是数组，可以是栏目id
     * @return boolean
     */
    public function deleteCatid($catid) {

        if (!$catid) {

            return false;
        }
        $where = array();
        //取得子栏目
        if (is_array($catid)) {

            $where['catid'] = array("IN", $catid);

            $catList = $this->where($where)->select();

            foreach ($catList as $cat) {

                //是否存在子栏目
                if ($cat['child'] && $cat['type'] == 0) {

                    $arrchildid = explode(",", $cat['arrchildid']);

                    unset($arrchildid[0]);

                    $catid = array_merge($catid, $arrchildid);
                }
            }

            $where['catid'] = array("IN", $catid);

        } else {

            $where['catid'] = $catid;

            $catInfo = $this->where($where)->find();
            if (is_object($catInfo)) {
                $catInfo = $catInfo->toArray();
            }
            //是否存在子栏目
            if (!empty($catInfo['child']) && $catInfo['type'] == 0) {

                $arrchildid = explode(",", $catInfo['arrchildid']);

                unset($arrchildid[0]);

                $catid = array_merge($arrchildid, array($catid));

                $where['catid'] = array("IN", $catid);
            }
        }
        //检查是否存在数据，存在数据不执行删除
        if (is_array($catid)) {

            $modeid = array();

            foreach ($catid as $cid) {

                $catinfo = getCategory($cid);

                if ($catinfo['modelid'] && $catinfo['type'] == 0) {

                    $modeid[$catinfo['modelid']] = $catinfo['modelid'];
                }
            }

            foreach ($modeid as $mid) {

                $tbname = ucwords(getModel($mid, 'tablename'));

                if (!$tbname) {

                    return false;
                }

                if ($tbname && Db::name($tbname)->where(array("catid" => array("IN", $catid)))->count()) {

                    return false;
                }
            }

        } else {

            $catinfo = getCategory($catid);

            $tbname = ucwords(getModel($catInfo['modelid'], 'tablename'));

            if (!$tbname && $catinfo['type'] == 0) {

                return false;
            }

            if ($tbname && $catinfo['type'] == 0 && Db::name($tbname)->where(array("catid" => $catid))->count()) {

                return false;
            }
        }

        $status = $this->where($where)->delete();

        //更新缓存
        cache('Category', NULL);
        //更新缓存
        hk_cache('Category', NULL); 
        $Dir = new \libs\util\Dir('');
        $Dir->delDir(RUNTIME_PATH . "cache/");
        $Dir->delDir(RUNTIME_PATH . "temp/");
        //更新开启其他方式的缓存
        \think\Cache::clear();

        if (false !== $status) {

            $this->extendFieldDel($where);

            //删除对应栏目的权限列表
            Db::name("Category_priv")->where($where)->delete();

            if (is_array($catid)) {

                //删除附件
                foreach ($catid as $cid) {

                    service("Attachment")->api_delete('catid-' . $cid);
                }

            } else {

                service("Attachment")->api_delete('catid-' . $catid);
            }

            return true;

        } else {

            return false;
        }
    }

    /**
     * 获取子栏目ID列表
     * @staticvar type $categorys 静态变量 栏目数据
     * @param type $catid 栏目id
     * @return string 返回栏目子列表，以逗号隔开
     */
    public function getArrchildid($catid) {
        if (!$this->categorys) {
            $this->categorys = hk_cache('Category');
        }
        $arrchildid = $catid;
        if (is_array($this->categorys)) {
            foreach ($this->categorys as $id => $cat) {
                if ($cat['parentid'] && $id != $catid && $cat['parentid'] == $catid) {
                    $arrchildid .= ',' . $this->getArrchildid($id);
                }
            }
        }
        return $arrchildid;
    }

    /**
     * 获取父栏目ID列表
     * @param integer $catid 栏目ID
     * @param array $arrparentid 父目录ID
     * @param integer $n 查找的层次
     */
    public function getArrparentid($catid, $arrparentid = '', $n = 1) {

        if (empty($this->categorys)) {

            $this->categorys = hk_cache('Category');
        }


        if ($n > 10 || !is_array($this->categorys) || !isset($this->categorys[$catid])) {

            return false;
        }

        //获取当前栏目的上级栏目ID
        $parentid = $this->categorys[$catid]['parentid'];

        //所有父ID
        $arrparentid = $arrparentid ? $parentid . ',' . $arrparentid : $parentid;

        if ($parentid) {

            $arrparentid = $this->getArrparentid($parentid, $arrparentid, ++$n);

        } else {

            $data_list = $this->categorys;

            $data_list[$catid]['arrparentid'] = $arrparentid;
        }

        return $arrparentid;
    }

    /**
     * 获取扩展字段
     * @param type $catid 栏目ID
     * @return boolean
     */
    public function getExtendField($catid) {

        if (empty($catid)) {

            return false;
        }

        $extendFieldLisr = Db::name('CategoryField')->where('catid',$catid)->select();

        foreach ($extendFieldLisr as $k => $rs) {

            $extendFieldLisr[$k]['setting'] = unserialize($rs['setting']);
        }
        
        return $extendFieldLisr;
    }

    /**
     * 删除某栏目下的扩展字段
     * @param type $where 删除条件
     * @return boolean
     */
    public function extendFieldDel($where) {
        if (empty($where)) {
            return false;
        }
        return Db::name('CategoryField')->where($where)->delete() !== false ? true : false;
    }

    /**
     * 扩展字段处理
     * @param type $catid 栏目ID
     * @param type $post 数据
     * @return boolean
     */
    public function extendField($catid, $post) 
    {

        if (empty($catid) || intval($catid) < 1 || empty($post)) {

            return false;
        }

        // config('TOKEN_ON', false);

        //时间
        $time = time();

        //栏目信息
        $info = $this->where(array('catid' => $catid))->find()->toarray();

        if (empty($info)) {

            return false;
        }

        $info['setting'] = unserialize($info['setting']);

        //删除不存在的选项
        if (!empty($post['extenddelete'])) {

            $extenddelete = explode('|', $post['extenddelete']);

            Db::name('CategoryField')->where(array('fid' => array('IN', $extenddelete)))->delete();
        }

        //查询出该栏目扩展字段列表
        $extendFieldLisr = array();

        foreach (Db::name('CategoryField')->where('catid',$catid)->field('fieldname')->select() as $rs) {

            $extendFieldLisr[] = $rs['fieldname'];
        }

        //检查是否有新增加字段
        if (!empty($post['extend_config']) && is_array($post['extend_config'])) {

            $rule = [
                // ['catid','require','栏目ID不能为空！'],
                ['fieldname','require|/^[a-z_0-9]+$/i','键名不能为空！|键名只支持英文、数字、下划线！'],
                ['type','require','类型不能为空！'],
                // ['aa','require']
                // ['fieldname','/^[a-z_0-9]+$/i','键名只支持英文、数字、下划线！'],
            ];

            $flag = true;

            $validate = new Validate($rule);

            foreach ($post['extend_config'] as &$rs){

                //如果已经存在则跳过
                if (in_array($rs['fieldname'], $extendFieldLisr)) {

                    continue;
                }

                $result = $validate->check($rs);

                if ( !$result ) {

                    $this->error = '扩展字段 '.$rs['fieldname'].$validate->getError();

                    return false;
                }

                $rs['catid'] = $catid;

                $rs['createtime'] = $time;

                $setting = $rs['setting'];

                if ($rs['type'] == 'radio' || $rs['type'] == 'checkbox') {

                    $option = array();

                    $optionList = explode("\n", $setting['option']);

                    if (is_array($optionList)) {

                        foreach ($optionList as $rs) {

                            $rs = explode('|', $rs);

                            if (!empty($rs)) {

                                $option[] = array(

                                    'title' => $rs[0],

                                    'value' => $rs[1],
                                );
                            }
                        }

                        $setting['option'] = $option;
                    }
                }

                $rs['setting'] = serialize($setting);
            }

            foreach ($post['extend_config'] as $field => $rs) {

                //如果已经存在则跳过
                if (in_array($field, $extendFieldLisr)) {

                    continue;
                }

                $fieldId = Db::name('CategoryField')->insertGetId($rs);

                if ($fieldId) {

                    $extendFieldLisr[] = $field;
                }
            }
        }
        //值更新
        $extend = array();

        if (!empty($post['extend']) || is_array($post['extend'])) {
            foreach ($post['extend'] as $field => $value) {
                if (in_array($field, $extendFieldLisr)) {
                    $extend[$field] = $value;
                }
            }
            $info['setting']['extend'] = $extend;
        }

        //更新栏目
        $status = $this->where('catid',$catid)->update(
            array(
                'setting' => serialize($info['setting']),
            )
        );

        //删除缓存
        getCategory($catid, '', true);
        return $status !== false ? true : false;
    }

    //刷新栏目索引缓存
    public function category_cache() {
        $data = $this->order("listorder ASC")->select()->toArray();
        $CategoryIds = array();
        foreach ($data as $r) {
            $CategoryIds[$r['catid']] = array(
                'catid' => $r['catid'],
                'parentid' => $r['parentid'],
//                'arrparentid' => $r['arrparentid'],
//                'child' => $r['child'],
//                'arrchildid' => $r['arrchildid'],
//                'type' => $r['type'],
            );
        }
        hk_cache("Category", $CategoryIds);
        return $CategoryIds;
    }

    public function checkCatdir($data)
    {
        $find = Db::name('category')->where(['parentdir'=>$data['parentdir'],'catdir'=>$data['catdir']])->find();

        if ($find) {
            return false;
        }
    }


    /**
     * 执行URL更新操作
     * @param type $data 数据
     * @return boolean
     */
    private function urls($data) {
        if (!$data['inputtime'] || !$data['id'] || !$data['catid']) {
            return false;
        }
        $url_model = new \libs\system\Url;
        $urls = $url_model->show($data);
        $aa = ContentModel::getInstance(getCategory($data['catid'], 'modelid'))->where('id',$data['id'])->update(array('url' => $urls['url']));
        return $urls['url'];
    }

    /**
     * 修复栏目数据
     * @param type $categorys 需要修复的栏目数组
     * @return boolean
     */
    protected function repair($categorys) {
        if (is_array($categorys)) {
            foreach ($categorys as $catid => $cat) {
                //外部栏目无需修复
                if ($cat['type'] == 2) {
                    continue;
                }

                //获取父栏目ID列表
                $arrparentid = model("content/Category")->getArrparentid($catid);
                //栏目配置信息反序列化
                $setting = unserialize($cat['setting']);
                //获取子栏目ID列表
                $arrchildid = model("content/Category")->getArrchildid($catid);

                //检查所有父id 子栏目id 等相关数据是否正确，不正确更新
                if ($categorys[$catid]['arrparentid'] != (string)$arrparentid || $categorys[$catid]['arrchildid'] != (string)$arrchildid) {
                    model("content/Category")->where(array('catid' => $catid))->update(array('arrparentid' => $arrparentid, 'arrchildid' => $arrchildid));
                }
                $url_model = new \libs\system\Url;
                //获取父栏目路径
                $parentdir = $url_model->get_categorydir($catid);
                //获取栏目名称
                $catname = iconv('utf-8', 'gbk', $cat['catname']);
                //返回拼音
                $letters = gbk_to_pinyin($catname);
                $letter = strtolower(implode('', $letters));
                $url_model = new \libs\system\Url;
                //取得栏目相关地址和分页规则
                $category_url = $url_model->category_url($catid);
                if (false == $category_url) {
                    return false;
                }
                $url = $category_url['url'];
                //更新数据
                $save = array();
                //更新URL
                if ($cat['url'] != $url) {
                    $save['url'] = $url;
                }
                if ($categorys[$catid]['parentdir'] != $parentdir || $categorys[$catid]['letter'] != $letter) {
                    $save['parentdir'] = $parentdir;
                    $save['letter'] = $letter;
                }
                if (count($save) > 0) {
                    model("content/Category")->where(array('catid' => $catid))->update($save);
                }
                //刷新单栏目缓存
                getCategory($catid, '', true);
            }
        }
        return true;
    }

}
